<!DOCTYPE html>
<html lang="zh-cn">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        html {
            min-width: 1060px;
            background: #fff;
        }

        body {
            width: 100%;
            max-width: 2560px;
            margin: 0 auto;
            background: #ccc;
            overflow: hidden;

            /* margin-top: 10px; */
        }

        canvas {
            object-fit: cover;
        }
    </style>
</head>

<body>
    <script>

        // 创建画布

        const canvasElem = document.createElement('canvas')

        // 缓存画布，双缓存解决高频刷新时的画面闪烁问题
        const tempCanvas = document.createElement('canvas')

        document.body.append(canvasElem)

        const ctx = canvasElem.getContext('2d')
        const tempCtx = tempCanvas.getContext('2d')


        // 设置画布大小
        // 依据：b站主页缩放至50%时，Banner显示的最大值
        const canvasSize = {
            w: 2560,
            h: 240
        }

        canvasElem.setAttribute('width', canvasSize.w)
        canvasElem.setAttribute('height', canvasSize.h)

        tempCanvas.width = canvasSize.w, tempCanvas.height = canvasSize.h


        // 设置填充样式为红色
        ctx.fillStyle = '#7bc6fc';
        // 填充整个 Canvas 画布
        ctx.fillRect(0, 0, 2560, 240);

        // 视频
        // 309.677px 774.194px
        // 167.226px 418.065px
        // 200 500


        const bubble1 = videoNode('./src/528d9376-f0fd-4445-9840-13e7559d6056.webm', {
            playbackRate: 3
        })
        const bubble2 = videoNode('./src/528d9376-f0fd-4445-9840-13e7559d6056.webm', {
            playbackRate: 1.5
        })

        const bubble3 = videoNode('./src/1671f963-c10d-4558-af99-e20a26c5a1f8.webm', {
            playbackRate: 1.5
        })

        function videoNode(vidSrc, options = {}) {
            const video = document.createElement('video')
            document.body.append(video)

            video.src = vidSrc
            video.muted = true
            video.loop = true
            video.autoplay = true
            video.style.opacity = 0
            video.style.position = 'absolute'

            for (let k in options) {
                video[k] = options[k]
            }

            return video
        }

        // 页面大小变更时触发
        function winResize() {

            const widthOffset = window.innerWidth - canvasSize.w

            if (widthOffset < 0) {
                canvasElem.style.marginLeft = widthOffset / 2 + 'px'
            } else {
                canvasElem.style.margin = '0 auto'
            }
        }

        fetch('./src/base.json')
            .then(res => res.text())
            .then(data => {
                // console.log(JSON.parse(data));

                // draw(JSON.parse(data), 100)
                draw(JSON.parse(data), 1)
            })


        const imgList = []


        /*  */
        let origin = null, offset = 0
        const offsetCalc = (weight = 0) => {
            return offset * 0.1 * weight
        }


        function draw(imgSet, duration = null) {
            tempCtx.fillStyle = '#7bc6fc'
            tempCtx.fillRect(0, 0, canvasElem.width, canvasElem.height)

            // tempCtx.clearRect(0, 0, canvasElem.width, canvasElem.height)
            // tempCtx.save()


            if (duration) {
                let i = 0, loadI = 0
                for (let k in imgSet) {
                    imgList[i] = {
                        elem: new Image(),
                        src: imgSet[k],
                        id: k
                    }

                    // 偏移权重
                    // const offsetWeight = Math.random()
                    let offsetWeight = 0, offsetTopWeight = 0, scaleFactor = 0.8, left = 0, top = 0



                    switch (k) {
                        case 'ce8c5e45230a6d3805baf60f5916f1cd441aac8e.png@1c.webp':
                            // 33
                            /*  */
                            offsetWeight = 0.4
                            left = -30
                            scaleFactor = 0.81
                            break;
                        case 'cbf19f3682dfb02e62557d07fefaf241a80296a1.png@1c.webp':
                            // 路人
                            offsetWeight = 0.56

                            // 插入泡泡3（被植物覆盖
                            i++
                            imgList[i] = {
                                elem: bubble3,
                                offsetWeight: 0,
                                offsetTopWeight: 0,
                                scaleFactor: 0.8,
                                left: 0,
                                top: 0,
                                id: './src/1671f963-c10d-4558-af99-e20a26c5a1f8.webm'
                            }


                            break;
                        case '8ea0e95a8e5fc85ae227810925dba1ace1e9fcba.png@1c.webp':
                            // 拉行李的路人
                            offsetWeight = 0.3
                            left = -20
                            break;
                        case '7998ca9f0bc267375fb7b45f75626d96806f94d7.png@1c.webp':
                            // 植物 13
                            offsetWeight = 0.9

                            // console.log(imgList[i-1].id);


                            break;
                        case 'd6c941cf2d5fc6c717173f7e3f166dbc444aa15b.png@1c.webp':
                            // 背景
                            offsetWeight = 0.06
                            break;
                        case '42485baddbca05d2c4c7710a0b76b74d303e06d7.png@1c.webp':
                            // 22看窗
                            /*  */
                            offsetWeight = 0.26
                            scaleFactor = 0.835
                            left = -72
                            top = -6
                            break;

                        case '09d0855b6b6d6965e8f02404777986237848c6c9.png@1c.webp':
                            // 大鲸鱼
                            offsetWeight = 0.78
                            left = -16
                            break;


                        // 斜向
                        case 'a43c6833d262301373234ffbd6934559d2ce7fb2.png@1c.webp':
                            offsetWeight = 0.6
                            offsetTopWeight = 0.18
                            left = -14

                            break;
                        case '142a486b8dd500a626a60b68ad993af8dabc8b55.png@1c.webp':
                            offsetWeight = 0.91
                            offsetTopWeight = 0.44
                            break;
                        // case 'd6c941cf2d5fc6c717173f7e3f166dbc444aa15b.png@1c.webp':
                        //     offsetWeight = 0.05
                        //     break;

                        default:
                            break;
                    }

                    imgList[i] = {
                        ...imgList[i],
                        ...{
                            offsetWeight: offsetWeight,
                            offsetTopWeight: offsetTopWeight,
                            scaleFactor: scaleFactor,
                            left: left,
                            top: top
                        }
                    }


                    setTimeout(() => {

                        const img = new Image()
                        img.src = imgSet[k]
                        img.onload = () => {
                            // tempCtx.globalAlpha = 0.2

                            // 缓存
                            loadI++

                            switch (k) {
                                case 'cd68251cde11936871237ca94360acb451bf7ed2.png@1c.webp':
                                    tempCtx.globalAlpha = 0.5
                                    break;

                                default:
                                    tempCtx.globalAlpha = 1
                                    break;
                            }


                            tempCtx.drawImage(img, left, top, img.width * scaleFactor, img.height * scaleFactor)
                            ctx.drawImage(tempCanvas, 0, 0)
                        }
                    }, duration * i)
                    i++
                }


                setTimeout(() => draw(), 1000 / 24 + (duration * Object.keys(imgSet).length))
            } else {
                // console.log(imgList);

                imgList.forEach((img, i) => {
                    switch (img.id) {
                        case 'cd68251cde11936871237ca94360acb451bf7ed2.png@1c.webp':
                            tempCtx.globalAlpha = 0.5
                            break;

                        default:
                            tempCtx.globalAlpha = 1
                            break;
                    }

                    // 复原动画
                    let left = offsetCalc(img.offsetWeight), top = offsetCalc(img.offsetTopWeight ?? 0)

                    if (img.latest && !origin) {
                        // 这里存在的精度问题暂时就不考虑了
                        left = img.latest.l * 0.6
                        img.latest.l = left

                        top = img.latest.t * 0.6
                        img.latest.t = top
                    } else {
                        img.latest = {
                            l: offsetCalc(img.offsetWeight),
                            t: offsetCalc(img.offsetTopWeight ?? 0)
                        }
                    }

                    // console.log(img);

                    tempCtx.drawImage(img.elem, img.left + left, img.top + top, img.width * img.scaleFactor, img.height * img.scaleFactor)

                    if (i >= imgList.length - 1) {
                        tempCtx.globalAlpha = 1

                        // 2560 / 2 - 1083.87 - 250 / 2
                        tempCtx.drawImage(bubble1, 71, 0, bubble1.videoWidth * 0.8, bubble1.videoHeight * 0.8)
                        // 2560 / 2 + 334.452 - 250 / 2
                        tempCtx.drawImage(bubble2, 1489, 0, bubble2.videoWidth * 1.5, bubble2.videoHeight * 1.5)

                        ctx.drawImage(tempCanvas, 0, 0)

                        setTimeout(() => draw(), 1000 / 24)
                    }
                })


                /* for (let k in imgSet) {
                    const img = new Image()
                    img.src = imgSet[k]
                    img.onload = function () {

                        // 缓存
                        // if (k == 'cd68251cde11936871237ca94360acb451bf7ed2.png@1c.webp') {
                        //     tempCtx.globalAlpha = 0.5

                        // } else {
                        //     tempCtx.globalAlpha = 1
                        // }
                        // console.log(k);

                        tempCtx.drawImage(this, 0, 0, img.width * scaleFactor, img.height * scaleFactor)

                        i++
                        if (i >= Object.keys(imgSet).length) {
                            ctx.drawImage(tempCanvas, 0, 0)

                            // 2560 / 2 - 1083.87 - 250 / 2
                            ctx.drawImage(bubble1, 71, 0, bubble1.videoWidth * 0.8, bubble1.videoHeight * 0.8)
                            // 2560 / 2 + 334.452 - 250 / 2
                            ctx.drawImage(bubble2, 1489, 0, bubble2.videoWidth * 1.5, bubble2.videoHeight * 1.5)

                            // setTimeout(() => draw(imgSet), 10000 / 12)
                        }
                    }
                } */
            }
        }

        window.addEventListener('mousemove', _ => {
            // console.log(_.target == canvasElem)

            // 判断鼠标进入判定区域
            if ((_.pageY >= canvasElem.offsetTop && _.pageY <= canvasElem.offsetTop + canvasElem.height)) {
                // 获取原始点
                if (origin != Number(origin)) {
                    origin = _.pageX
                }

                // 偏移量
                offset = _.pageX - origin



            } else {
                origin = null, offset = 0
            }

            // console.log(origin);

            // console.log(offset);

        })

        winResize()
        window.addEventListener('resize', () => {
            winResize()

            // console.log(window.innerWidth, window.innerHeight);

            // canvasElem.style.scale = window.innerWidth / canvasSize.w
            // canvasElem.style.marginLeft = '-50%'

        })

    </script>
</body>

</html>